package edu.iu.criminfo.voronoi;

import java.util.Iterator;
import java.util.List;

import edu.iu.criminfo.voronoi.cases.Case;
import edu.iu.criminfo.voronoi.gpsUtils.KMLFileWritter;
import edu.iu.criminfo.voronoi.init.InitiateCluster;
import edu.iu.criminfo.voronoi.init.ParseDataFile;
import edu.iu.criminfo.voronoi.kmeans.Cluster;
import edu.iu.criminfo.voronoi.kmeans.KMeans;
import edu.iu.criminfo.voronoi.object.Edge;
import edu.iu.criminfo.voronoi.object.Point;

public class Main {
	private static double swCornerX;
	private static double swCornerY;
	private static double neCornerX;
	private static double neCornerY;
	
	public static void main(String[] args) {
		String clusteringAlgorithm = null;

//		clusteringAlgorithm = "K-means";
		clusteringAlgorithm = "Modified_K-means";

		List<Case> caseList = ParseDataFile.parse("data/vehicle_access.txt");
		System.out.println(caseList.size() + " points are added");

		getBoundary(caseList);
		
		List<Cluster> clusterList = InitiateCluster
		.generateInitiateCluster(caseList, swCornerX, swCornerY, neCornerX, neCornerY);
		System.out.println(clusterList.size() + " centroids are generated");

		KMeans kmeans = new KMeans(clusterList, caseList, clusteringAlgorithm);
		kmeans.setConvergeThreshold(clusterList.get(0).getCenter().distance(
				clusterList.get(clusterList.size() - 1).getCenter()) / 100000);
		kmeans.startClustering();

		clusterList.remove(0); // first class always decayed
		
		for (Iterator<Cluster> it = clusterList.iterator(); it.hasNext();) {
			Cluster cluster = it.next();
			System.out.println(cluster.size());
			
			cluster.getBoundary();
			System.out.println("South West boundary is: " + cluster.getSwCornerX() + "\t" + cluster.getSwCornerY());
			System.out.println("North East boundary is: " + cluster.getNeCornerX() + "\t" + cluster.getNeCornerY());
		}
		
		Voronoi voronoi = new Voronoi();
		voronoi.Sort(clusterList);
		List<Edge> edgeList;
		//Amplify all the parameter to accommodate to the Voronoi class
		edgeList = voronoi.getEdges(swCornerX * 1000, swCornerY * 1000, neCornerX * 1000, neCornerY * 1000);
		for (Edge edge: edgeList) {
			edge.begin.coordinateX/=1000;
			edge.begin.coordinateY/=1000;
			edge.end.coordinateX/=1000;
			edge.end.coordinateY/=1000;
			System.out.println(edge.begin.coordinateX + "\t" + edge.begin.coordinateY);
			System.out.println(edge.end.coordinateX + "\t" + edge.end.coordinateY);
		}

		String kmlFile = "data/" + clusteringAlgorithm + ".kml";
		KMLFileWritter kml = new KMLFileWritter(kmlFile, clusteringAlgorithm);
		kml.writeKMLFileHeader();
		
		//Write all the points
		int i = 0;
		for (Cluster cluster : clusterList) {
			kml.appendCluster(cluster, i);
			i++;
		}
		
		//Write Voronoi Diagram
		for (Edge edge: edgeList) {
			kml.appendEdge(edge);
		}
		
		kml.writeKMLFileTail();

		kmeans.writeResultToFile("data/clusterd_crimes_normalKmeans.txt");
	}
	
	public static void getBoundary(List<Case> caseList) {
		swCornerX = caseList.get(0).getLocation().coordinateX;
		swCornerY = caseList.get(0).getLocation().coordinateY;
		neCornerX = swCornerX;
		neCornerY = swCornerY;
		
		for (Iterator<Case> it = caseList.iterator(); it.hasNext();) {
			Case aCase = it.next();
			Point point = aCase.getLocation();
			if (point.coordinateX < swCornerX) {
				swCornerX = point.coordinateX;
			} else if (point.coordinateX > neCornerX) {
				neCornerX = point.coordinateX;
			}
			if (point.coordinateY < swCornerY) {
				swCornerY = point.coordinateY;
			} else if (point.coordinateY > neCornerY) {
				neCornerY = point.coordinateY;
			}
		}
	}
}
